package zdream.pmfield.stage.buff.ailment;

import zdream.pmfield.data.foe.MoveAdditionalEffects;
import zdream.pmfield.stage.action.BuffAction;
import zdream.pmfield.stage.buff.foe.FoeStageBuff;
import zdream.pmfield.stage.message.FoeReceiveDamageMessage;
import zdream.pmfield.stage.object.FoeActor;

/**
 * <p>酸蚀, 每一回合 {@link zdream.pmfield.stage.Timeline#round} (这里不是一轮) 触发
 * <p>每次触发时, 如果 {@link FoeActor} 有护盾, 则护盾承受护盾最大值 1/10 或更少的伤害.
 * 当护盾消耗完时, 会随机让消耗品或物品变为不可用状态, 不会删物品, 战斗结束后恢复 TODO
 * </p>
 *
 * <p>
 * 酸蚀效果能自然恢复, 2 轮之后投骰子判断是否恢复.
 * 主要通过 {@link zdream.pmfield.data.foe.VStat#LUCK} 来决定是否恢复.
 * </p>
 *
 * @author Zdream
 * @date 2023-12-03
 * @since 0.0.1
 */
public class AcidBuff extends FoeStageBuff {
	public static final String CATEGORY = MoveAdditionalEffects.E_ACID;
	public final BuffSpan span;

	public float nextTriggerTime;

	public AcidBuff(FoeActor target) {
		super(target);
		span = new DurationBuffSpan()
				.withMinDuration(2)
				.withCheckRateFunction(duration -> duration * 30 - 90)
				.withStartTime(now());
		nextTriggerTime = now();
	}

	@Override
	public void init() {
		preventSameBuffBeforeFoeReceiveBuff();
		putAcidDamageActionToTimeline();
	}

	public void putAcidDamageActionToTimeline() {
		int maxShield = target.foe.maxShield;

		int damage = (maxShield <= 30) ?
				(int) Math.ceil((maxShield) / 10f) :
				(int) Math.ceil((maxShield + 60f) / 30);

		nextTriggerTime += 1;
		putBuffActionWithTime(buildTask(damage), nextTriggerTime);
	}

	private static String buildTask(int damage) {
		return String.format("damage=%d", damage);
	}

	private static int parseTask(String task) {
		return Integer.parseInt(task.split("=")[1]);
	}

	@Override
	public void doTask(BuffAction action) {
		// 检查是否痊愈
		boolean cured = span.checkIsNeedCured();
		if (cured) {
			return;
		}

		int damage = parseTask(action.task);
		takeDamage(damage);

		// 创建下一次任务
		putAcidDamageActionToTimeline();
	}

	private void takeDamage(int damage) {
		int actualDamage = damage;

		final int currentShield = target.currentShield;
		if (currentShield < damage) {
			actualDamage = currentShield;
		}

		if (actualDamage > 0) {
			final FoeReceiveDamageMessage damageMessage = new FoeReceiveDamageMessage(target)
					.withDamage(damage)
					.withTitle(CATEGORY)
					.withHpFrom(target);

			target.receiveDamage(actualDamage);
			pushMessage(damageMessage.withHpTo(target));
		}
	}

	@Override
	public String getCategory() {
		return CATEGORY;
	}

	@Override
	public String toString() {
		return "酸蚀";
	}
}
